using System;
using FineCollection.Intf;




namespace FineCollection.Cont
{
    public class ArrList<T> : ArrBaseCollection<T>, WRandomList<T>
    {

        /// <summary>
        /// Constructs an empty array-based list.
        /// </summary>
        /// <param name="firstIndex">origin index (index of the first item).</param>
        public ArrList(int firstIndex) 
            : base(firstIndex)
        {}


        /// <summary>
        /// Constructs an empty array-based list with the specified capacity.
        /// </summary>
        /// <param name="firstIndex">origin index (index of the first item).</param>
        /// <param name="cap">neccessary capacity.</param>
        public ArrList(int firstIndex, int cap)
            : base(firstIndex, cap)
        {}


        /// <summary>
        /// Adds the specified item to the end of the list.
        /// </summary>
        /// <param name="item">item to add.</param>
        public void Add(T item)
        {
            InternalAddItem(item);
        }


        /// <summary>
        /// Represents a quick writeable indexed access to the specified item.
        /// </summary>
        /// <remarks>
        /// The given index must be in [ FirstIndex .. LastIndex ] inclusive.
        /// </remarks>
        /// <param name="index">index of item to access.</param>
        /// <exception cref="CollectionIsEmpty">when the collection is empty.</exception>
        /// <exception cref="IndexOutOfBoundsException">when index is incorrect.</exception>
        /// <seealso cref="RRandomList{T}.FirstIndex"/>
        /// <seealso cref="RRandomList{T}.LastIndex"/>
        public new T this[int index]
        {
            get 
            {           
                int intIndex = CalcInternalIndex(index);
                return ar[intIndex];
            }

            set
            {
                int intIndex = CalcInternalIndex(index);
                ar[intIndex] = value;
            }
        }


        ///<summary>
        /// Inserts the specified item into the specified position.
        ///</summary>
        /// <remarks>
        /// After the operation completed, 
        /// the specified item will be at the specified postion.
        /// Items were at this and next positions will be shifted right.
        /// </remarks>
        ///<param name="index"></param>
        ///<param name="item"></param>
        public void IncludeAt(int index, T item)
        {
            this.InsertElement(index, item);
        }


        /// <summary>
        /// Excludes the specified by index item from the collection and returns it.
        /// </summary>
        /// <param name="index">index of item to exclude.</param>
        /// <returns>just excluded item.</returns>
        public T ExcludeAt(int index)
        {
            T theItem = this[index];
            this.RemoveElementAt(index);
            return theItem;
        }
    }
}
